package vn.pyco.prez.tapestry.services.internal;

import java.util.Locale;

import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Link;
import org.apache.tapestry5.internal.EmptyEventContext;
import org.apache.tapestry5.internal.services.ArrayEventContext;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.services.ComponentClassResolver;
import org.apache.tapestry5.services.ComponentEventLinkEncoder;
import org.apache.tapestry5.services.ComponentEventRequestParameters;
import org.apache.tapestry5.services.PageRenderRequestParameters;
import org.apache.tapestry5.services.PersistentLocale;
import org.apache.tapestry5.services.Request;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import vn.pyco.prez.tapestry.services.AppHelper;

public class AppHelperImpl implements AppHelper {
	private static final Logger logger = LoggerFactory.getLogger(AppHelperImpl.class);
	
	@Inject
	private ComponentEventLinkEncoder _componentEventLinkEncoder;
	
	@Inject 
	private ComponentClassResolver _componentClassResolver;
	
    @Inject
    private TypeCoercer _typeCoercer;
    
	@Inject
	private PersistentLocale _locale;
	
	@Inject
	private Request _request;
	

	/*
	 * (non-Javadoc)
	 * @see vn.pyco.prez.tapestry.services.AppHelper#getEventLink(java.lang.String, java.lang.String, java.lang.Object[])
	 */
    public Link getEventLink(String pageName, String eventName, Object... context) {
        ComponentEventRequestParameters parameters =
        	new ComponentEventRequestParameters(pageName, pageName, "", eventName, new ArrayEventContext(_typeCoercer, context), new EmptyEventContext());
                
	    Link eventLink = _componentEventLinkEncoder.createComponentEventLink(parameters, false);
	    return eventLink;
    }
    
    /*
     * (non-Javadoc)
     * @see vn.pyco.prez.tapestry.services.AppHelper#getEventLink(java.lang.Class, java.lang.String, java.lang.Object[])
     */
	public Link getEventLink(Class<?> pageName, String eventName, Object... context){
		return getEventLink(getPageNameFromClass(pageName), eventName, context);
	}

    /*
     * (non-Javadoc)
     * @see vn.pyco.prez.tapestry.services.AppHelper#getEventLink(java.lang.String, java.lang.String)
     */
    public Link getEventLink(String pageName, String eventName) {
        ComponentEventRequestParameters parameters = 
        	
        	new ComponentEventRequestParameters(pageName, pageName, "", eventName, new EmptyEventContext(), new EmptyEventContext());
                
	    Link eventLink = _componentEventLinkEncoder.createComponentEventLink(parameters, false);
	    return eventLink;
    }

    /*
     * (non-Javadoc)
     * @see vn.pyco.prez.tapestry.services.AppHelper#getEventLink(java.lang.Class, java.lang.String)
     */
    public Link getEventLink(Class<?> pageName, String eventName) {
		return getEventLink(getPageNameFromClass(pageName), eventName);
	}

    /*
     * (non-Javadoc)
     * @see vn.pyco.prez.tapestry.services.AppHelper#getCurrentLocale()
     */
    public Locale getCurrentLocale() {
    	if(_locale.isSet()) {
    		return _locale.get();
    	} else {
    		return _request.getLocale();
    	}
    }

	@Override
	public Link getPageLink(String pageName) {
		PageRenderRequestParameters parameters = new PageRenderRequestParameters(pageName, new EmptyEventContext(), false);
		return _componentEventLinkEncoder.createPageRenderLink(parameters);
	}

	@Override
	public Link getPageLink(String pageName, Object... context) {
		PageRenderRequestParameters parameters;
		if(context.length == 1 && context[0] == null)  {
			parameters = new PageRenderRequestParameters(pageName, new EmptyEventContext(), false);
		} else {
			parameters = new PageRenderRequestParameters(pageName, new ArrayEventContext(_typeCoercer, context), false);
		}
		return _componentEventLinkEncoder.createPageRenderLink(parameters);
	}

	@Override
	public Link getPageLink(Class<?> pageClass) {
		return getPageLink(getPageNameFromClass(pageClass));
	}
	
	public Link getPageLink(Class<?> pageClass,Object... context) {
		return getPageLink(getPageNameFromClass(pageClass), context);
	}
	
	public String getPageNameFromClass(Class<?> pageClass) {
		return _componentClassResolver.resolvePageClassNameToPageName(pageClass.getName());
	}

	@Override
	public String getPageURI(Class<?> pageClass) {
		String uri = getPageLink(pageClass).toURI();
		if(logger.isDebugEnabled()) {
			logger.debug("Processed URI : " + uri);
		}
		return uri;
	}
	
	@Override
	public String getPageURI(Class<?> pageClass, Object... context) {
		String uri = getPageLink(pageClass, context).toURI();
		if(logger.isDebugEnabled()) {
			logger.debug("Processed URI : " + uri);
		}
		return uri;
	}

	@Override
	public String getCurrentPageUrl(ComponentResources ressources) {
		return getPageLink(ressources.getPageName()).toURI();
	}

	@Override
	public String getBaseUrlEventLink(ComponentResources resources) {
		return resources.createEventLink("REPLACE_EVENT").toURI();
	}

	@Override
	public String getRootUrl(boolean addTrailingSlash) {
		return addTrailingSlash ? _request.getContextPath() + "/" : _request.getContextPath();
	}

	@Override
	public String getFQNRootUrl(boolean addTrailingSlash) {
		String baseHost = _request.getServerName();
		if(_request.getServerPort() == 443){
			baseHost = "https://" + baseHost;
		} else {
			baseHost = "http://" + baseHost;
		}
		if ( _request.getServerPort() != 80) {
			baseHost = baseHost + ":" + _request.getServerPort();
		}
		return baseHost + getRootUrl(addTrailingSlash);
	}
	
}
